package com.gurumades.jsonform.client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.dispatch.client.ExceptionHandler;
import net.customware.gwt.dispatch.client.standard.StandardDispatchAsync;

import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.gurumades.jsonform.client.presenter.JsonFormPresenter;
import com.gurumades.jsonform.shared.dispatch.GetFormAction;
import com.gurumades.jsonform.shared.dispatch.GetFormResult;
import com.gurumades.jsonform.shared.dispatch.SubmitFormAction;
import com.gurumades.jsonform.shared.dispatch.SubmitFormResult;

public class JsonFormController {
	private HasWidgets container;
	private JsonFormPresenter jsonPresenter;
	private JSONObject displayObject;

	
	private HashMap<String, JSONValue> jsonForms = new HashMap<String, JSONValue>();

	private String formID;
	

	DispatchAsync dispatch = new StandardDispatchAsync(new ExceptionHandler() {

		@Override
		public Status onFailure(Throwable e) {
			Window.alert("Dispatch of action failled :"
					+ e.getLocalizedMessage());

			return Status.STOP;
		}
	});
	
	protected Long buildID;
	private IFormController delegate;

	public JsonFormController() {
	}

	public void go(HasWidgets container, HashMap<String, Serializable> buildParams,
			final String formID, IFormController delegate) {
		this.container = container;
		this.formID = formID;
		this.displayObject = delegate.getDisplayObject(formID);
		this.delegate = delegate;
		
		if (jsonPresenter == null) {
			jsonPresenter = new JsonFormPresenter(new JsonFormView(), displayObject, this, formID);
		}

		dispatch.execute(new GetFormAction(formID, buildParams),
				new AsyncCallback<GetFormResult>() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Dispatch of action failled :"
								+ caught.getLocalizedMessage());
					}

					@Override
					public void onSuccess(GetFormResult result) {
						JSONValue displayFields = JSONParser.parseLenient(result
								.getJsonForm());
						
						jsonForms.put(formID, displayFields);
						
						jsonPresenter.setBuildID(result.getBuildID());
						JsonFormController.this.buildID = result.getBuildID();
						jsonPresenter.go(JsonFormController.this.container, JsonFormController.this);
					}

				});
	}


	public HashMap<String, JSONValue> flush() {
		return jsonPresenter.flush();
	}

	public boolean hasErrors() {
		return !jsonPresenter.getErrors().isEmpty();
	}

	public JSONValue getDisplayFields(String formID) {
		return jsonForms.get(formID);
	}

	public void submit() {
		HashMap<String, JSONValue> formValues = jsonPresenter.flush();
		
		if (hasErrors()) {
			
		}else {
			delegate.onSubmit(formID, formValues);
		}
	}

	public void cancel() {
		delegate.onCancel();
	}
}
